/**
 * 格式化日期
 * @param {number|string|Date} date - 时间戳(秒)或日期对象
 * @param {string} format - 格式，默认 'YYYY/MM/DD'
 * @returns {string} 格式化后的日期字符串
 */
export function formatDate(date, format = 'YYYY/MM/DD') {
  if (!date) return '';
  
  // 如果是时间戳（秒），转换为毫秒
  const d = typeof date === 'number' && date < 1e12 ? new Date(date * 1000) : new Date(date);
  
  // 如果日期无效，返回空字符串
  if (isNaN(d.getTime())) return '';
  
  const pad = n => n.toString().padStart(2, '0');
  
  const replacements = {
    'YYYY': d.getFullYear(),
    'MM': pad(d.getMonth() + 1),
    'DD': pad(d.getDate()),
    'HH': pad(d.getHours()),
    'mm': pad(d.getMinutes()),
    'ss': pad(d.getSeconds())
  };
  
  return format.replace(/(YYYY|MM|DD|HH|mm|ss)/g, match => replacements[match] || match);
}

/**
 * 获取指定类型的日期范围（本日/本周/本月）
 * @param {string} type - 日期类型：today(本日)、week(本周)、month(本月)
 * @param {Date} [customDate] - 可选：自定义基准日期（默认取当前日期）
 * @returns {Array<string>} 日期范围数组，格式 ['开始日期', '结束日期']（YYYY-MM-DD）
 * @throws {Error} 传入无效type时抛出错误
 */
export function getDateRangeByType(type, customDate = new Date()) {
  // 工具函数：日期补零（确保月/日为两位数）
  const padZero = (num) => num.toString().padStart(2, '0');

  // 复制基准日期（避免修改原日期对象）
  const baseDate = new Date(customDate);
  const year = baseDate.getFullYear();
  const month = baseDate.getMonth(); // 月份：0-11（需注意）
  const date = baseDate.getDate();

  // 根据类型计算日期范围
  switch (type.toLowerCase()) {
    // 1. 本日：开始和结束都是当天
    case 'today':
      return [
        `${year}-${padZero(month + 1)}-${padZero(date)}`,
        `${year}-${padZero(month + 1)}-${padZero(date)}`
      ];

    // 2. 本周：开始（周日）- 结束（周六），可调整为周一为第一天（见注释）
    case 'week':
      // 获取当前是本周第几天（0=周日，1=周一，...，6=周六）
      const dayOfWeek = baseDate.getDay();
      // 计算本周第一天（周日）：当前日期 - (本周第几天) 天
      const weekStart = new Date(baseDate);
      weekStart.setDate(date - dayOfWeek);
      // 计算本周最后一天（周六）：本周第一天 + 6 天
      const weekEnd = new Date(weekStart);
      weekEnd.setDate(weekStart.getDate() + 6);
      // 返回格式化后的本周范围
      return [
        `${weekStart.getFullYear()}-${padZero(weekStart.getMonth() + 1)}-${padZero(weekStart.getDate())}`,
        `${weekEnd.getFullYear()}-${padZero(weekEnd.getMonth() + 1)}-${padZero(weekEnd.getDate())}`
      ];

    // 3. 本月：开始（1号）- 结束（当月最后一天）
    case 'month':
      // 本月第一天（1号）
      const monthStart = new Date(year, month, 1);
      // 本月最后一天（下个月1号 - 1天）
      const monthEnd = new Date(year, month + 1, 0);
      // 返回格式化后的本月范围
      return [
        `${monthStart.getFullYear()}-${padZero(monthStart.getMonth() + 1)}-${padZero(monthStart.getDate())}`,
        `${monthEnd.getFullYear()}-${padZero(monthEnd.getMonth() + 1)}-${padZero(monthEnd.getDate())}`
      ];

    // 无效类型处理
    default:
      throw new Error(`无效的日期类型：${type}，仅支持 today/week/month`);
  }
}
/**
 * 计算预期租金收益（包含总收益、每月收益和每日收益）
 * @param {number} purchasePrice - 采购价格（必填，如1000.00）
 * @param {number} userRate - 托管经营用户的收益率（百分比，如10表示10%，必填）
 * @param {number} periods - 期数（如12期，必填）
 * @param {number} [daysInYear=365] - 一年的天数，默认365天
 * @returns {Object} 包含总租金收益、每月收益和每日收益的对象（均保留两位小数）
 * @throws {Error} 当参数不合法时抛出错误
 */
export function calculateRentalIncome(purchasePrice, userRate, periods, daysInYear = 365) {
    // 参数校验
    if (typeof purchasePrice !== 'number' || purchasePrice <= 0) {
        throw new Error('采购价格必须是正数');
    }
    if (typeof userRate !== 'number' || userRate < 0) {
        throw new Error('收益率必须是非负数');
    }
    if (typeof periods !== 'number' || periods <= 0 || !Number.isInteger(periods)) {
        throw new Error('期数必须是正整数');
    }
    if (typeof daysInYear !== 'number' || daysInYear <= 0) {
        throw new Error('天数必须是正数');
    }

    // 计算总租金收益（包含本金），先保留两位小数确保精度
    const totalRentalIncome = Number((purchasePrice * (1 + userRate / 100)).toFixed(2));

    // 计算每月收益（使用精确的小数处理，确保1100÷12=91.66）
    const monthlyIncome = Number((Math.floor((totalRentalIncome / periods) * 100) / 100).toFixed(2));

    // 计算每日收益（保留两位小数）
    const dailyIncome = Number((totalRentalIncome / daysInYear).toFixed(2));

    return {
        totalRentalIncome, // 总租金收益
        monthlyIncome, // 每月收益
        dailyIncome // 每日收益
    };
}
/**
 * 兼容 H5 + 微信小程序 + 支付宝小程序 的 docx 文本读取工具
 * 依赖：jszip
 * 安装：npm install jszip
 */
import JSZip from './jszip.min'

// 判断是否存在 DOMParser（H5有，小程序没有）
function parseXML(xmlText) {
    if (typeof DOMParser !== 'undefined') {
        // ✅ H5 环境
        return new DOMParser().parseFromString(xmlText, 'application/xml')
    } else {
        // ⚙️ 小程序环境：手动解析文本
        // 这里只简单提取 <w:t> 标签内容，适合纯文字文档
        const matches = [...xmlText.matchAll(/<w:t[^>]*>(.*?)<\/w:t>/g)]
        return matches.map(m => m[1].replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&'))
    }
}

/**
 * 读取 .docx 文件内容
 * @param {string} url 文件网络地址
 * @returns {Promise<string>} 提取的纯文本内容
 */
export async function readDocxText(url) {
    try {
        // 1️⃣ 下载文件为二进制
        const [err, res] = await uni.request({
            url,
            responseType: 'arraybuffer'
        })

        if (err || res.statusCode !== 200) {
            throw new Error('下载失败')
        }
        // 2️⃣ 解压 .docx 文件
        const zip = await JSZip.loadAsync(res.data)
        // 3️⃣ 获取 word/document.xml
        const docXml = await zip.file('word/document.xml').async('text')
        // 4️⃣ 解析 XML 内容
        const parsed = parseXML(docXml)
        let textContent = ''
        if (Array.isArray(parsed)) {
            // 小程序环境
            textContent = parsed.join('')
        } else {
            // H5 环境
            const nodes = parsed.getElementsByTagNameNS('*', 't')
            for (let node of nodes) {
                textContent += node.textContent
            }
        }

        // 5️⃣ 处理段落分隔（可选）
        textContent = textContent.replace(/([^\n])(\n)([^\n])/g, '$1\n\n$3')
        let text = xmlToRichTextHtml(textContent)
        console.log(text)
        return text

        // return textContent || '文档为空'
    } catch (e) {
        console.error('readDocxText error:', e)
        throw e
    }
}
/**
 * XML格式合同文档转UniApp rich-text兼容HTML
 * 支持：标题居中、段落缩进、表格样式、列表格式、文本加粗/字号、自动换行
 * @param {string} xmlContent - 原始XML文档内容
 * @returns {string} 处理后的HTML字符串
 */
export function xmlToRichTextHtml(xmlContent) {
    let html = xmlContent;

    // ================= 1. 预处理：清除冗余XML标签与命名空间 =================
    html = html
        .replace(/w:/g, '') // 移除XML命名空间前缀（如<w:pPr>→<pPr>）
        .replace(/<\?xml[^>]*\?>/g, '') // 移除XML声明头
        .replace(/xmlns="[^"]+"/g, '') // 移除命名空间定义
        .replace(/xml:space="preserve"/g, 'data-preserve="true"') // 标记需保留空格的文本
        .replace(/<w:del[^>]*>[\s\S]*?<\/w:del>/g, '') // 移除删除标记内容
        .replace(/<bookmarkStart[^>]*>|<\/bookmarkEnd>/g, ''); // 移除书签标记

    // ================= 2. 解析表格结构（核心：保留原表格样式与内容） =================
    // 2.1 表格容器转换：<tbl>→<table>，添加边框与宽度
    html = html.replace(/<tbl[^>]*>/g, '<table style="width:100%;border-collapse:collapse;margin:1.5em 0;border:1px solid #333;">');
    html = html.replace(/<\/tbl>/g, '</table>');

    // 2.2 表格行转换：<tr>→<tr>，添加行高
    html = html.replace(/<trPr[^>]*>/g, (match) => {
        const heightMatch = match.match(/trHeight w:val="(\d+)"/);
        const height = heightMatch ? `${Math.round(parseInt(heightMatch[1])/20)}px` : '40px';
        return `<tr style="height:${height};border-bottom:1px solid #333;">`;
    });
    html = html.replace(/<\/trPr>/g, '</tr>');

    // 2.3 表格单元格转换：<tc>→<td>，保留背景色、对齐、内边距
    html = html.replace(/<tcPr([^>]*)>/g, (match, attrs) => {
        // 解析背景色（如D6DCE5）
        const bgMatch = attrs.match(/fill="([A-Fa-f0-9]+)"/);
        const bgColor = bgMatch ? `background-color:#${bgMatch[1]};` : '';
        // 解析对齐方式
        const alignMatch = attrs.match(/vAlign w:val="([a-z]+)"/);
        const align = alignMatch ? `vertical-align:${alignMatch[1]};` : 'vertical-align:middle;';
        // 单元格样式：内边距、边框、文本居中
        return `<td style="${bgColor}${align}padding:12rpx 8rpx;border-right:1px solid #333;text-align:center;font-size:24rpx;">`;
    });
    html = html.replace(/<\/tcPr>/g, '</td>');

    // 2.4 清除表格内冗余标签
    html = html.replace(/<tblGrid[^>]*>[\s\S]*?<\/tblGrid>/g, '');
    html = html.replace(/<tblBorders[^>]*>[\s\S]*?<\/tblBorders>/g, '');
    html = html.replace(/<tblLayout[^>]*>/g, '');
    html = html.replace(/<tblCellMar[^>]*>/g, '');


    // ================= 3. 解析段落结构（核心：标题居中、段落缩进、行高） =================
    // 3.1 段落容器转换：<pPr>→<p>，解析对齐、行高、首行缩进
    html = html.replace(/<pPr([^>]*)>/g, (match, attrs) => {
        const styles = [];

        // 解析文本对齐（标题居中、正文左对齐）
        const alignMatch = attrs.match(/jc w:val="([a-z]+)"/);
        if (alignMatch) {
            const alignMap = { center: 'text-align:center;', left: 'text-align:left;', right: 'text-align:right;' };
            styles.push(alignMap[alignMatch[1]] || 'text-align:left;');
        }

        // 解析行高（XML中line值转px）
        const lineMatch = attrs.match(/spacing w:line="(\d+)"/);
        if (lineMatch) {
            const lineHeight = Math.round(parseInt(lineMatch[1])/100);
            styles.push(`line-height:${lineHeight > 30 ? lineHeight : 30}px;`);
        }

        // 解析首行缩进（如480→24px，对应2个中文字符）
        const indentMatch = attrs.match(/ind w:firstLine="(\d+)"/);
        if (indentMatch) {
            const indent = Math.round(parseInt(indentMatch[1])/20);
            styles.push(`text-indent:${indent > 0 ? indent : 24}px;`);
        }

        // 段落基础样式：上下间距、字号、宽度
        styles.push('margin:1em 0;padding:0 4rpx;font-size:28rpx;width:100%;');
        return `<p style="${styles.join('')}">`;
    });
    html = html.replace(/<\/pPr>/g, '</p >');

    // 3.2 清除段落内冗余标签
    html = html.replace(/<r[^>]*>/g, '');
    html = html.replace(/<\/r>/g, '');


    // ================= 4. 解析文本样式（核心：加粗、字号、字体） =================
    // 4.1 文本样式容器转换：<rPr>→<span>，解析加粗、字号、字体
    html = html.replace(/<rPr([^>]*)>/g, (match, attrs) => {
        const styles = [];

        // 解析加粗（<b val="1">→font-weight:bold）
        if (attrs.includes('b val="1"') || attrs.includes('bCs')) {
            styles.push('font-weight:bold;');
        }

        // 解析字号（XML中sz val="40"→20px，1sz=0.5px）
        const szMatch = attrs.match(/sz w:val="(\d+)"/);
        if (szMatch) {
            const fontSize = Math.round(parseInt(szMatch[1]) * 0.5);
            // 适配移动端：字号转rpx（1px=2rpx）
            styles.push(`font-size:${fontSize < 12 ? 24 : fontSize*2}rpx;`);
        }

        // 解析字体（默认宋体，适配中文显示）
        if (attrs.includes('rFonts hint="eastAsia"')) {
            styles.push('font-family:SimSun,宋体,sans-serif;');
        }

        // 解析文本颜色（默认深灰，避免过浅）
        const colorMatch = attrs.match(/color w:val="([A-Fa-f0-9]+)"/);
        if (colorMatch) {
            styles.push(`color:#${colorMatch[1] || '333333'};`);
        }

        // 保留空格（标记为data-preserve的文本）
        if (attrs.includes('data-preserve="true"')) {
            styles.push('white-space:pre-wrap;');
        }

        return styles.length ? `<span style="${styles.join('')}">` : '<span>';
    });
    html = html.replace(/<\/rPr>/g, '</span>');

    // 4.2 文本内容转换：<t>→提取文本，清除空标签
    html = html.replace(/<t([^>]*)>/g, '');
    html = html.replace(/<\/t>/g, '');
    html = html.replace(/<span><\/span>/g, '');


    // ================= 5. 格式优化（核心：自动换行、清除冗余） =================
    html = html
        // 自动换行：替换XML中的换行符为<br>
        .replace(/\r?\n/g, '<br>')
        // 清除连续空格（保留文本内有意义空格，合并无意义空格）
        .replace(/(\s|&nbsp;){3,}/g, (match) => {
            return match.includes('&nbsp;') ? match : ' ';
        })
        // 清除空段落
        .replace(/<p[^>]*><br\/?><\/p>/g, '')
        .replace(/<p[^>]*><\/p>/g, '')
        // 清除残留未处理的XML标签
        .replace(/<\/?[^pst][^>]*>/g, '')
        // 移动端适配：表格单元格文本换行
        .replace(/<td([^>]*)>/g, (match) => {
            return match.replace('text-align:center;', 'text-align:center;word-break:break-all;');
        });

    return html;
}